import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import ItemDetail from '../views/ItemDetail.vue'
import Cart from '../views/Cart.vue'
import LoginPage from '../views/Login/LoginPage.vue'
import AdminLogin from '../views/Admin/AdminLogin.vue'
import AdminDashboard from '../views/Admin/AdminDashboard.vue'

// 创建一个路由实例，使用 Vue Router 的 createRouter 函数
const router = createRouter({
  // 设置路由的历史模式为 HTML5 History 模式，并使用 import.meta.env.BASE_URL 作为基础路径
  // createWebHistory 是 Vue Router 提供的用于创建 HTML5 History 模式的函数
  // import.meta.env.BASE_URL 是 Vite 提供的环境变量，代表项目的基础路径
  history: createWebHistory(import.meta.env.BASE_URL),
  // 定义路由规则数组，每个对象代表一个路由规则
  routes: [
    {
      // 路由匹配的路径，当访问根路径时触发该路由
      path: '/',
      // 该路由的名称，方便在代码中通过名称来引用该路由
      name: 'home',
      // 该路由对应的组件，当路由匹配成功时，会渲染该组件
      component: Home
    },
    {
      // 路由匹配的路径，:id 是一个动态参数，可以匹配任意字符串
      // 例如访问 /item/123 会匹配该路由，并且 123 会作为 id 参数传递给组件
      path: '/item/:id',
      // 该路由的名称，方便在代码中通过名称来引用该路由
      name: 'item',
      // 该路由对应的组件，当路由匹配成功时，会渲染该组件
      component: ItemDetail
    },
    {
      // 路由匹配的路径，当访问 /cart 路径时触发该路由
      path: '/cart',
      // 该路由的名称，方便在代码中通过名称来引用该路由
      name: 'cart',
      // 该路由对应的组件，当路由匹配成功时，会渲染该组件
      component: Cart
    },
    {
      // 定义一个路由规则，当访问路径为 /login 时触发该路由
      path: '/login',
      // 该路由的名称，方便在代码中通过名称来引用该路由
      name: 'login',
      // 该路由对应的组件，当路由匹配成功时，会渲染 LoginPage 组件
      component: LoginPage
    },
    {
      // 定义一个路由规则，当访问路径为 /admin/login 时触发该路由
      path: '/admin/login',
      // 该路由的名称，方便在代码中通过名称来引用该路由
      name: 'admin-login',
      // 该路由对应的组件，当路由匹配成功时，会渲染 AdminLogin 组件
      component: AdminLogin,
      // 路由元信息，标记该路由为公共路由，无需登录即可访问
      meta: { isPublic: true }
    },
    {
      // 定义一个路由规则，当访问路径为 /admin/dashboard 时触发该路由
      path: '/admin/dashboard',
      // 该路由的名称，方便在代码中通过名称来引用该路由
      name: 'admin-dashboard',
      // 该路由对应的组件，当路由匹配成功时，会渲染 AdminDashboard 组件
      component: AdminDashboard,
      // 路由元信息，标记该路由需要管理员权限才能访问
      meta: { requiresAdmin: true }
    }
  ]
})

// 全局前置守卫，在每次路由跳转前执行该函数
// router.beforeEach 是 Vue Router 提供的全局前置守卫函数，它会在每次路由跳转前被调用。
// 该函数接收三个参数：
// to: 即将要进入的目标路由对象，包含了目标路由的各种信息，如路径、参数、元信息等。
// from: 当前导航正要离开的路由对象，包含了当前路由的各种信息。
// next: 一个函数，用于控制路由的跳转行为。调用 next() 表示继续路由跳转；
// 调用 next('path') 或 next({ path: 'path' }) 可以重定向到指定路径；
// 调用 next(false) 会取消当前的导航。
router.beforeEach((to, from, next) => {
  // 从 localStorage 中获取用户登录状态，判断用户是否已登录
// localStorage 是浏览器提供的一种本地存储机制，用于在浏览器中持久化存储数据。
// getItem 是 localStorage 对象的一个方法，用于从本地存储中获取指定键名对应的值。
// 'isLoggedIn' 是存储在 localStorage 中的键名，代表用户的登录状态。
// 通过比较获取的值是否等于 'true'，来判断用户是否已经登录，并将结果赋值给变量 isLoggedIn。
const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'
  // 从 localStorage 中获取管理员令牌，判断当前用户是否为管理员
  const isAdmin = localStorage.getItem('admin-token') !== null
  
  // 管理员路由守卫
  // 检查即将访问的路由是否需要管理员权限
  if (to.matched.some(record => record.meta.requiresAdmin)) {
    // 如果用户不是管理员，则重定向到管理员登录页面，并记录原目标路径
    if (!isAdmin) {
      next({ path: '/admin/login', query: { redirect: to.fullPath } })
      return
    }
  }
  
  // 普通用户路由守卫
  // 检查即将访问的路由是否不是公共路由，并且路径不以 /admin 开头
// 判断即将访问的路由是否不存在标记为公共路由的记录，并且路径不以 /admin 开头
// to.matched 是一个数组，包含了与目标路由匹配的所有路由记录
// some 是数组的一个方法，用于检测数组中是否至少有一个元素满足指定条件
// record 是数组中的每个路由记录对象
// record.meta.isPublic 是路由记录对象中的元信息，用于标记该路由是否为公共路由
// to.path 是目标路由的路径
// startsWith 是字符串的一个方法，用于检测字符串是否以指定的子字符串开头
if (!to.matched.some(record => record.meta.isPublic) && 
    !to.path.startsWith('/admin')) {
    // 如果用户未登录且目标路径不是登录页面，则重定向到登录页面，并记录原目标路径
    if (!isLoggedIn && to.path !== '/login') {
// next 是 Vue Router 全局前置守卫中的一个函数，用于控制路由的跳转行为。
// 调用 next 并传入一个对象可以实现重定向到指定路径的功能。
// { path: '/login', query: { redirect: to.fullPath } } 是传递给 next 函数的参数对象。
// path: '/login' 表示要重定向到的目标路径为 '/login'，即登录页面。
// query: { redirect: to.fullPath } 表示在重定向时，会在 URL 中添加查询参数，
// 其中 'redirect' 是参数名，to.fullPath 是参数值，to.fullPath 代表即将访问的完整路径，
// 这样在用户登录成功后可以根据这个参数重定向回原来想要访问的页面。
// 调用 return 语句是为了提前结束当前的路由守卫函数，避免后续代码继续执行。
next({ 
  path: '/login',
  query: { redirect: to.fullPath }
})
return
    }
  }
  
  // 允许路由跳转
  next()
})

// 导出路由实例，供其他模块使用
export default router
